package com.xiangxiao.rpan.data.mqtt;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.UUID;

/**
 * @Projectname: rpan-data
 * @Author: xiangxiao
 * @Email: 573768011@qq.com
 * @Data:2024/6/3 0:35
 */
@Component
public class MyMqttServer {
  @Value("${mqtt.server.url}")
  private String host;
  @Value("${mqtt.server.username}")
  private String userName;
  @Value("${mqtt.server.password}")
  private String password;
  @Resource
  private MqttDataCallback mqttDataCallback;

  private static Logger logger = LogManager.getLogger(MyMqttServer.class);
  private static final String TOPICNAMEPREFIX = "alarm/";
  private String clientId = createUUID();
  private static MqttClient mqttClient;
  private static final Object mqttServerConnectedLock = new Object();

  /**
   * @PostConstruct 注解的作用是服务初始化启动完成后会主动执行有该注解的方法
   * 在该注解中执行能保证取到mqttServerUrl,usrname,password
   */
  @PostConstruct
  public void start(){
    logger.info("MQTT连接数据初始化成功，开始连接....");
    connect();
  }

  /**
   * 连接MQTT服务端
   */
  public void connect(){
    //防止重复创建MQTTClient实例
    if (mqttClient == null){
      try {
        mqttClient = new MqttClient(host,clientId,new MemoryPersistence());
        //MqttDataService是接收订阅topic数据推送的回调
        mqttClient.setCallback(mqttDataCallback);
      } catch (MqttException e) {
        e.printStackTrace();
      }
    }
    MqttConnectOptions options = getOptions();
    //判断拦截状态
    if (!mqttClient.isConnected()){
      try {
        mqttClient.connect(options);
        logger.info("[MQTT] 连接成功！");
      } catch (MqttException e) {
        e.printStackTrace();
      }
    }else {
      try {
        mqttClient.disconnect();
        mqttClient.connect(options);
        logger.info("[MQTT] 连接成功！");
      } catch (MqttException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * 配置MQTT连接信息
   * @return
   */
  public MqttConnectOptions getOptions(){
    MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
    //是否清除Session
    mqttConnectOptions.setCleanSession(false);
    //MQTT服务器用户名
    mqttConnectOptions.setUserName(userName);
    //MQTT服务器密码
    mqttConnectOptions.setPassword(password.toCharArray());
    //MQTT连接超时时间,10s
    mqttConnectOptions.setConnectionTimeout(10);
    //设置MQTT心跳时间,20s
    mqttConnectOptions.setKeepAliveInterval(20);
    System.out.println(mqttConnectOptions);
    return mqttConnectOptions;
  }

  /**
   *断线重连
   */
  public void reConnect() throws MqttException {
    if (null != mqttClient){
      MqttConnectOptions options = getOptions();
      mqttClient.connect(options);
      logger.info("[MQTT] 重连成功！");
    }
  }


  public static String createUUID(){
    UUID uuid = UUID.randomUUID();
    String uuidStr = String.valueOf(uuid);
    String uuidStr2 = uuidStr.replaceAll("-","");
    return uuidStr2;
  }

  public static void post(String topicNameSuffix, String msg) {
    try {
      if (!mqttClient.isConnected()) {
        synchronized (mqttServerConnectedLock) {
          if (!mqttClient.isConnected()) {
            mqttClient.connect();
          }
        }
      }
      logger.debug("mqtt ready to post msg:" + topicNameSuffix + "," + msg);
      MqttTopic topic = mqttClient.getTopic(TOPICNAMEPREFIX + topicNameSuffix);
      MqttMessage message = new MqttMessage();
      message.setQos(0);
      message.setRetained(false);
      message.setPayload(msg.getBytes());
      MqttDeliveryToken token = topic.publish(message);
      token.waitForCompletion();
    } catch (Exception e) {
      logger.error("error to post mqtt message", e);
    }
  }
}
